import java.io.Serializable;

/**
 *	Fecha de Creacion: 14 de noviembre de 2011 
 *	Descripcion:	Esta clase puede representar cualquier tipo de dato u objeto dentro de LisP.
 *					Permite tratar a todos los tipos de datos como una sola clasificacion lo cual es 
 *					necesario a la hora de parsear una lista y ordenarla
 */


/**
 * @author Medrano, Debroy
 *
 */


public class Generico implements Serializable{
	
	/**
	 * valorAtomo	contiene un valor tipo Atomo que corresponda a este dato Generico
	 */
	Atomo valorAtomo;
	
	/**
	 * valorLista	contiene un valor tipo Lista que corresponda a este dato Generico
	 */
	Lista valorLista;
	
	/**
	 * valorFuncion	contiene un valor tipo Funcion que corresponda a este dato Generico
	 */
	Funcion valorFuncion;
	
	/**
	 * esAtomo		indica si este Generico puede contiene un Atomo
	 */
	boolean esAtomo;
	
	/**
	 * esLista		indica si este Generico contiene una Lista
	 */
	boolean esLista;
	
	/**
	 * esFuncion		indica si este Generico contiene una funcion
	 */
	boolean esFuncion;
	
	
	
	/**
	 * Generico 		Constructor: Permite crear un nuevo Generico que contiene un Atomo a partir de un atomo
	 * @param atomo
	 */
	public Generico(Atomo atomo){
		this.valorAtomo = atomo;
		esAtomo = true;
		esLista = false;
		esFuncion = false;
	}
	
	
	/**
	 * Generico		Constructor: 	Permite crear un nuevo Generico que contiene una Lista a partir de una Lista
	 * @param lista
	 */
	public Generico(Lista lista){
		this.valorLista = lista;
		esAtomo = false;
		esLista = true;
		esFuncion = false;
		
	}
	
	/**
	 * Generico		Constructor:	Permite crear un nuevo Generico que contiene una Funcion a partir de una Funcion
	 * @param funct
	 */
	public Generico(Funcion funct){
		this.valorFuncion =funct;
		esAtomo = false;
		esLista = false;
		esFuncion = true;
		
	}

	/**
	 * getValorAtomo	Permite obtener el valor tipo Atomo que contiene este Generico o NULL si no contiene un Atomo
	 * @return
	 */
	public Atomo getValorAtomo() {
		return valorAtomo;
	}
	
	/**
	 * setValorAtomo	Permite establecer el valor Atomo para este Generico
	 * @return
	 */
	public void setValorAtomo(Atomo valorAtomo) {
		this.valorAtomo = valorAtomo;
		this.esAtomo = true;
		this.esLista = false;
		this.esFuncion = false;
	}

	/**
	 * getValorLista	Permite obtener el valor tipo Lista que contiene este Generico o NULL si no contiene una Lista
	 * @return
	 */
	public Lista getValorLista() {
		return valorLista;
	}
	
	/**
	 * setValorLista	Permite establecer el valor Lista para este Generico
	 * @return
	 */
	public void setValorLista(Lista valorLista) {
		this.valorLista = valorLista;
		this.esLista = true;
		this.esAtomo = false;
		this.esFuncion = false;
	}

	/**
	 * getValorFuncion	Permite obtener el valor tipo Funcion que contiene este Generico o NULL si no contiene una Funcion
	 * @return
	 */
	public Funcion getValorFuncion() {
		return valorFuncion;
	}

	/**
	 * setValorFuncion	Permite establecer el valor Funcion para este Generico
	 * @return
	 */
	public void setValorFuncion(Funcion valorFuncion) {
		this.valorFuncion = valorFuncion;
		this.esFuncion = true;
		this.esAtomo = false;
		this.esLista = false;
	}

	/**
	 * isAtomo		Permite conocer si este Generico contiene un Atomo
	 * @return
	 */
	public boolean isAtomo() {
		return esAtomo;
	}

	/**
	 * setValorAtomo	Permite establecer el valor Atomo para este Generico
	 * @return
	 */
	public void setEsAtomo(boolean esAtomo) {
		this.esAtomo = esAtomo;
	}

	/**
	 * isLista		Permite conocer si este Generico contiene una Lista
	 * @return
	 */
	public boolean isLista() {
		return esLista;
	}
	
	/**
	 * setEsLista	Permite establecer si este Generico contiene o no una lista
	 * @param esLista
	 */
	public void setEsLista(boolean esLista) {
		this.esLista = esLista;
	}

	/**
	 * isFuncion	Permite conocer si este Generico contiene o no una Funcion
	 * @return
	 */
	public boolean isFuncion() {
		return esFuncion;
	}

	/**
	 * setEsFuncion	Permite establecer si este Generico contiene una Funcion
	 * @param esFuncion
	 */
	public void setEsFuncion(boolean esFuncion) {
		this.esFuncion = esFuncion;
	}
	
	/**
	 * toString		Permite obtener una representacion tipo String de este Generico
	 */
	public String toString(){
		if(isAtomo()){
			return valorAtomo.toString();
		}else if(isLista()){
			return valorLista.toString();
		}else{
			return valorFuncion.toString();
		}	
	}

}
